/*
 *  Copyright 2012.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package org.opu.pc.ui.util;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.Collection;
import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;

import static javax.swing.JOptionPane.*;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import org.opu.pc.ui.client.actions.AbstractAction;

/**
 *
 */
public class Options {

    public static final int CH_NEW_OPTION = YES_OPTION;
    public static final int CH_OK_OPTION = NO_OPTION;
    public static final int CH_CANCEL_OPTION = CANCEL_OPTION;

    public static class Option {
        public int code;
        public Object source;

        public Option(int code, Object source) {
            this.code = code;
            this.source = source;
        }

        public void setCode(int code) {
            this.code = code;
        }

        public void setSource(Object source) {
            this.source = source;
        }
    }

    public static void error(Exception ex){
        error(null, ex);
    }

    public static void error(String msg){
        error(msg, null);
    }

    public static void error(String msg, Exception ex){
        if (msg == null){
            msg = String.valueOf(getExceptionMessage(ex));
        }

        JEditorPane ep = new JEditorPane("text", msg);
        ep.setSize(400, 400);
        ep.setEditable(false);
        ep.setBackground(UIManager.getColor("Panel.background"));
        try {
            showMessageDialog(null,
                    ep,
                    ResourceHandle.getApplicationTitle(),
                    ERROR_MESSAGE);
        } catch (Exception exception) {
        }
    }

    public static String select(String msg){
        return JOptionPane.showInputDialog(null,
                msg,
                ResourceHandle.getApplicationTitle() + " - " + msg,
                QUESTION_MESSAGE);
    }

    public static boolean choise(String msg){
        Object[] options = new Object[]{
            AbstractAction.getText("Ok"),
            AbstractAction.getText("Cancel")
        };

        int n = 0;
        try {
            n = JOptionPane.showOptionDialog(null,
                    msg,
                    ResourceHandle.getApplicationTitle() + " - " + msg,
                    YES_NO_OPTION,
                    QUESTION_MESSAGE,
                    null,
                    options,
                    options[0]);
        } catch (Exception exception) {
            n = NO_OPTION;
        }

        return YES_OPTION == n;
    }

    public static Option choise(String msg, final Collection<?> list){
        final DefaultListModel listModel = new DefaultListModel();
        for (Object object : list) {
            listModel.addElement(object);
        }
        final JList jl = new JList(listModel);
        jl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        final Option selectedValue = new Option(CANCEL_OPTION, null);
        final JDialog d = new JDialog();
        d.setModal(true);
        d.setTitle(ResourceHandle.getApplicationTitle() + " - " + msg);

        JButton options[] = new JButton[]{
            new JButton(GUIUtils.getAction("New", new GUIUtils.ActionListener() {
                @Override public void actionPerformed(ActionEvent e) throws Exception {
                    selectedValue.setCode(CH_NEW_OPTION);
                    d.dispose();
                }
            })),
            new JButton(GUIUtils.getAction("Delete", new GUIUtils.ActionListener() {
                @Override public void actionPerformed(ActionEvent e) throws Exception {
                    Object v = jl.getSelectedValue();
                    if (v != null){
                        if (!list.remove(v)) {
                            throw new RuntimeException("Can't remove element");
                        }
                        listModel.remove(jl.getSelectedIndex());
                    }
                }
            })),
            new JButton(GUIUtils.getAction("Ok", new GUIUtils.ActionListener() {
                @Override public void actionPerformed(ActionEvent e) throws Exception {
                    Object sv = jl.getSelectedValue();
                    if (sv != null) {
                        selectedValue.setCode(CH_OK_OPTION);
                        selectedValue.setSource(sv);
                        d.dispose();
                    }
                }
            })),
            new JButton(GUIUtils.getAction("Cancel", new GUIUtils.ActionListener() {
                @Override public void actionPerformed(ActionEvent e) throws Exception {
                    selectedValue.setCode(CH_CANCEL_OPTION);
                    d.dispose();
                }
            }))
        };

        int h = GUIUtils.DEFAULT_SPACE / 2;
        Box b = Box.createHorizontalBox();
        for (JButton btn : options) {
            b.add(Box.createHorizontalStrut(h));
            b.add(btn);
            b.add(Box.createHorizontalStrut(h));
        }

        JPanel pane = new JPanel(new BorderLayout(16, 16));
        pane.add(GUIUtils.hCenter(GUIUtils.vBorder(new JLabel(msg), h * 2, h / 4)), BorderLayout.NORTH);
        pane.add(GUIUtils.hBorder(GUIUtils.vBorder(new JScrollPane(jl), h / 4, h / 2)));
        pane.add(GUIUtils.hCenter(GUIUtils.vBorder(b, h / 2, h)), BorderLayout.SOUTH);

        d.getContentPane().add(pane);
        GUIUtils.setSize(d, 340);
        d.setLocationRelativeTo(null);
        d.setVisible(true);

        return selectedValue;
    }

    private static String getExceptionMessage(Exception exception){
        Throwable ex = exception;
        String msg = null;

        while(ex != null && msg == null){
            String lm = ex.getLocalizedMessage();
            if (lm != null && !lm.trim().isEmpty()){
                msg = lm;
            }
            ex = ex.getCause();
        }

        return msg;
    }

}
